package com.liu.network.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.io.IOException;

/**
 * Netty 是一个基于NIO的客户端_服务器端的编程框架。例如：基于TCP和UDP的socket服务开发。
 * Netty客户端
 *
 */
public class NettyClient {

    private static String ip = "192.168.31.116";

    private static int port = 9998;

    public static void main(String[] args) throws Exception {
        new NettyClient().connect(ip, port);
    }

    public void connect(String ip, int port) throws IOException {
        //设置一个多线程循环器
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        //客户端启动类
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(workerGroup);
        //指定所使用的NIO传输channel
        bootstrap.channel(NioSocketChannel.class);
        //指定客户端初始化处理
        bootstrap.handler(new ClientIniterHandler());
        // TCP_NODELAY就是用于启用或关闭Nagle算法。
        //如果要求高实时性，有数据发送时就马上发送，就将该选项设置为true关闭Nagle算法；
        //如果要减少发送次数减少网络交互，就设置为false等累积一定大小后再发送。默认为false。
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        try {
            System.out.println("start to connect...");
        	// 绑定端口,同步等待绑定操作成功
            ChannelFuture channelFactory = bootstrap.connect(ip, port).sync();
            // 等待服务器链路关闭后main函数退出
            channelFactory.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.exit(1);
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
    
    public class ClientIniterHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            //注册管道
            ChannelPipeline pipeline = socketChannel.pipeline();
            pipeline.addLast("NettyClientHandler1", new NettyClientHandler1());
        }
    }

//    class ClientHandler extends ChannelInboundHandlerAdapter {
//        @Override
//        public void channelActive(ChannelHandlerContext ctx) throws Exception {
//            System.out.println("channel is activated.");
//
//            final ChannelFuture f = ctx.writeAndFlush(Unpooled.copiedBuffer("HelloNetty".getBytes()));
//            f.addListener(new ChannelFutureListener() {
//                public void operationComplete(ChannelFuture future) throws Exception {
//                    System.out.println("msg send!");
//                    //ctx.close();
//                }
//            });
//
//
//        }
//
//        @Override
//        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//            try {
//                ByteBuf buf = (ByteBuf)msg;
//                System.out.println(buf.toString());
//            } finally {
//                ReferenceCountUtil.release(msg);
//            }
//        }
//    }
}